/********************************************************************************
 * Copyright(c) 2020-2025 BST All rights reserved.
 * - Filename
 * - Author
 * - Version V1.0.0
 * - Date    2024/08/28
 * - Brief
 * - FunctionList:
 ******************************************************************************
 * History:
 *
 *
 *
 ******************************************************************************
 */
#pragma once

#include "Lidar.hpp"
#include "LsLidarCh128x1.h"
#include "UdpSocketClient.h"
#include "TimeUtil.h"
#include <condition_variable>
#include <deque>
#include <mutex>

namespace lslidar {

class LsLidarAdapter : public lidar::Lidar {
public:
  LsLidarAdapter(const uint32_t &id, const uint16_t &msop_port,
                 const uint16_t &difop_port);
  ~LsLidarAdapter();
  void start(
      std::function<void(std::shared_ptr<lpc::LidarProtoPointCloud> &&)>) override;
  void stop() override;

protected:
  const uint32_t _id;
  const uint16_t _msopPort;
  const uint16_t _difopPort;

private:
  bool _isExit{true};
  TimeUtil::FpsCalc _fps{};
  std::shared_ptr<UdpClient> _msop;
  std::shared_ptr<UdpClient> _difop;
  std::shared_ptr<LslidarCh128x1> _lidar{nullptr};
  std::shared_ptr<std::thread> _msopRecvThread{nullptr};
  std::shared_ptr<std::thread> _difopRecvThread{nullptr};
  std::shared_ptr<std::thread> _packageThread{nullptr};
  std::mutex _mtx;
  std::condition_variable _condition;
  std::deque<std::shared_ptr<lpc::LidarProtoPointCloud>> _lidarFrameDeque{};
  void recvDifopLoop();
  void recvMsopLoop();
  void
  processLoop(const std::function<void(std::shared_ptr<lpc::LidarProtoPointCloud> &&)>
                  &callback);
  void pointsCallback(const uint64_t &tm,
                      const std::vector<LidarPoint> &points);
};
} // namespace lslidar